/**
 * OSAmI: Open Source Ambient Intelligence
 * Copyright (C) 2010 Bull S.A.S.
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */

package org.osami.gateway.display.internal;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.ipojo.annotations.Bind;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Property;
import org.apache.felix.ipojo.annotations.Unbind;
import org.osami.gateway.alarm.IAlarm;
import org.osami.gateway.storage.IAlarmStorage;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.service.log.LogService;

@Component
@Instantiate
public class DisengageAlarmsServlet extends HttpServlet {
	
	/**
	 * serial version UID.
	 */
	private static final long serialVersionUID = 6630397067435699201L;

	@Property(value = Constants.DEFAULT_DISENGAGE_ALIAS)
	private String alias;
	
	private IAlarmStorage storage;
	
	private LogService logger;

	@Bind
	public void bindHttpService(HttpService httpService) throws ServletException, NamespaceException {
		httpService.registerServlet(alias, this, null, null);
	}

	@Unbind
	public void unbindHttpService(HttpService httpService) {
		httpService.unregister(alias);
	}
	
	@Bind
	public void bindAlarmStorage(IAlarmStorage storage) {
		this.storage = storage;
	}
	
	@Bind
	public void bindLogService(LogService logger) {
		this.logger = logger;
	}

	private void doGetPost(final HttpServletRequest req,
                           final HttpServletResponse resp)
            throws ServletException, IOException {
		PrintWriter writer = resp.getWriter();
		
		writer.println("<html>");
		
		// HTML Head
		// ---------------------------------------------------
		writer.println("<head>");
		writer.println(" <title>Alarms disengaged at " + new Date() + "</title>");
		writer.println("</head>");
		
		// HTML Body
		// ---------------------------------------------------
		writer.println("<body>");
		
		printPageTitle(writer);

		// Process Alarm IDs
		String[] values = req.getParameterValues(Constants.DISENGAGED_ALARM);
		
		if (values != null) {
			printDisengagedAlarmsTable(writer, values);
		} else {
			// No parameters, do nothing
			// but prints an informative message
			writer.println("<p>");
			writer.println("No alarms selected to be disengaged.");
			writer.println("</p>");
		}
		
		printBackToDisplayAlarmsForm(writer);
		
		writer.println("</body>");
		
		writer.println("</html>");
	}
	
	@Override
	protected void doGet(final HttpServletRequest req,
                         final HttpServletResponse resp)
			throws ServletException, IOException {

		doGetPost(req, resp);
	}

	@Override
	protected void doPost(final HttpServletRequest req,
                          final HttpServletResponse resp)
			throws ServletException, IOException {

		doGetPost(req, resp);
	}

	private void printDisengagedAlarmsTable(PrintWriter writer, String[] values) {

		writer.println("<table width='100%' cellpadding='0'>");
		// Print table headers
		writer.println("<thead><tr>");
		// Print each column name here
		printAlarmTableHeaders(writer);
		writer.println("</tr></thead>");
		
		// Print table body
		writer.println("<tbody>");

		for (String identifier : values) {
			try {
				IAlarm alarm = storage.remove(identifier);
				alarm.disengage();
				printRowSuccess(writer, alarm);
			} catch (Throwable throwable) {
				logger.log(LogService.LOG_WARNING, "Alarm disengagement for " + identifier + " has failed.", throwable);
				printRowFailure(writer, identifier, throwable.getMessage());
			}
		}

		writer.println("</tbody>");
		writer.println("</table>");
	}

	private void printPageTitle(PrintWriter writer) {
		writer.println("<h1>Alarms disengaged</h1>");
	}

	private void printBackToDisplayAlarmsForm(PrintWriter writer) {
		writer.println("<form action='" + Constants.DEFAULT_DISPLAY_ALIAS + "' method='POST'>");
		printRightAligned(writer, "<input type='submit' value='See Active alarms' />");
		writer.println("</form>");
	}

	private void printRightAligned(PrintWriter writer, String content) {
		writer.println("<div style='text-align:right;'>");
		writer.println(content);
		writer.println("</div>");
	}

	private void printAlarmTableHeaders(PrintWriter writer) {
		writer.println("<th>Identifier</th>");
		writer.println("<th>Severity</th>");
		writer.println("<th>Message</th>");
		writer.println("<th>Date</th>");
	}

	private void printRowSuccess(PrintWriter writer, IAlarm alarm) {
		// Green background
		writer.println("<tr style='background-color:#9AFE2E'>");
		printTableCell(writer, alarm.getIdentifier());
		printTableCell(writer, alarm.getSeverity().name());
		printTableCell(writer, alarm.getMessage());
		printTableCell(writer, alarm.getGenerationDate().toString());
		writer.println("</tr>");
	}

	private void printRowFailure(PrintWriter writer, String identifier, String message) {
		// Red background
		writer.println("<tr style='background-color:#F78181'>");
		String content = "Cannot disengage alarm (id:" + identifier + "): " + message;
		printTableCell(writer, 4, content);
		writer.println("</tr>");
	}

	private void printTableCell(PrintWriter writer, String content) {
		printTableCell(writer, 0, content);
	}

	private void printTableCell(PrintWriter writer, int colSpan, String content) {
		if (colSpan > 1) {
			writer.println("<td colspan='" + colSpan + "'>" + content + "</td>");
		}
		writer.println("<td>" + content + "</td>");
	}
	
}
